#include "lxz_config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <time.h>

#ifdef LXZAT_WIN32
#include <windows.h>
#endif /* LXZAT_WIN32 */

#ifdef LXZAT_LINUX
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <linux/sockios.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#include <errno.h>
#endif /* LXZAT_LINUX */

#include "lxz_types.h"
#include "os_port.h"
#include "lxz_sysloger.h"
#include "lxz_debug.h"
#include "lxz_ring.h"
#include "lxz_string.h"
#include "lxz_dstring.h"
#include "lxz_atc_req.h"
#include "lxz_urc_table.h"

#include "lxz_dbg_vmem.h"

static FILE* gfp_fd_sysloger = NULL;
static uint16 gi_id_ippacket = 0xCC;

static char gsp_mon_string[][4] = 
{
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

static uint16 lxzpcap_iphdr_checksum(uint16 * p_dst_buffer, sint32 i_nb_data)
{
    uint32 cksum = 0;

    while (i_nb_data > 1)
    {
        cksum += *p_dst_buffer++;
        i_nb_data = i_nb_data - 2;
    }

    if (i_nb_data)
    {
        cksum = cksum + *(uint08 *)p_dst_buffer;
    }

    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum = cksum + (cksum >> 16);
    return (uint16)(~cksum);
}

sint32 lxzpcap_sysloger_open(uint08* u_rel_dir)
{
    int i_ret_val = 0;

    char llbuf[63];
    int i_str_len = 0;
    FILE* fp_fd_curfile = NULL;
    sint08* p_tmp_dir = NULL;
    sint32 i_dir_exist = 0;
    
    time_t atime;
    int i_cur_year;
    int i_cur_mon;
    int i_cur_day;
    int i_cur_hour;
    int i_cur_min;
    int i_cur_sec;
    struct tm* p = NULL;

    pcap_filehdr_t a_pcap_filehdr;

    time(&atime);
    p = gmtime(&atime);

    memset(llbuf, 0, sizeof(llbuf));
    i_cur_year = p->tm_year+1900;
    i_cur_mon = p->tm_mon+1;
    i_cur_day = p->tm_mday;
    i_cur_hour = p->tm_hour+8;
    i_cur_min = p->tm_min;
    i_cur_sec = p->tm_sec;

#if 0
	sprintf(llbuf, "./lxzatflow%d%02d%02d%02d%02d%02d.pcap", i_cur_year, 
        i_cur_mon, i_cur_day, i_cur_hour, i_cur_min, i_cur_sec);
#else
    sprintf(llbuf, "./lxzatflow%d%02d%02d.pcap", i_cur_year, i_cur_mon, i_cur_day);
#endif

    fp_fd_curfile = fopen(llbuf, "wb+");
    if (fp_fd_curfile == NULL)
    {
        return i_ret_val;
    }

    i_ret_val = 1;
    gfp_fd_sysloger = fp_fd_curfile;


    a_pcap_filehdr.ut_pcap_magic = 0xA1B2C3D4;
    a_pcap_filehdr.ut_ver_major = 0x0002;
    a_pcap_filehdr.ut_ver_minor = 0x0004;
    a_pcap_filehdr.ut_cur_timezone = 0x00000000;
    a_pcap_filehdr.ut_cur_timestamp = 0x00000000;
    a_pcap_filehdr.ut_max_snaplength = 8192;
    a_pcap_filehdr.ut_cur_linktype = 0x00000001;
    fwrite(&(a_pcap_filehdr), 1, sizeof(pcap_filehdr_t), fp_fd_curfile);
    fflush(fp_fd_curfile);

    return i_ret_val;
}

sint32 lxzpcap_sysloger_printf(const char * vfmt, ...)
{
    char llbuf[512];

    va_list ap;
    int i_nb_data = 0;
	int i_nb_free = 0;

    time_t atime;
    int i_cur_year;
    int i_cur_mon;
    int i_cur_day;
    int i_cur_hour;
    int i_cur_min;
    int i_cur_sec;
    struct tm* p = NULL;
    FILE* fp_fd_curfile = gfp_fd_sysloger;

    struct timeval tv;
    uint16 i_nb_payload = 0;
    uint16 i_iphdr_checksum = 0;
    pcap_packethdr_t a_pcap_packethdr;
    pcap_packet_mac_t a_pcap_packet_mac;
    pcap_packet_iphdr_t a_pcap_packet_iphdr;
    pcap_packet_udphdr_t a_pcap_packet_udphdr;

    if (fp_fd_curfile != NULL)
    {
        time(&atime);
        p = gmtime(&atime);
        
        i_cur_year = p->tm_year+1900;
        i_cur_mon = p->tm_mon;
        i_cur_day = p->tm_mday;
        i_cur_hour = p->tm_hour;
        i_cur_min = p->tm_min;
        i_cur_sec = p->tm_sec;

        i_nb_free = sizeof(llbuf);
        memset(llbuf, 0, i_nb_free);
        i_nb_data = sprintf(llbuf, "<30>%s %2d %02d:%02d:%02d N360 LATServer[2021]: ", 
            gsp_mon_string[i_cur_mon], i_cur_day, 
            i_cur_hour, i_cur_min, i_cur_sec);

        i_nb_free = i_nb_free - i_nb_data;
        va_start(ap,vfmt);
        i_nb_data = vsnprintf(&(llbuf[i_nb_data]), i_nb_free, vfmt, ap);
        va_end(ap);

        i_nb_data = strlen(llbuf);
        i_nb_payload = i_nb_data + 8;
        a_pcap_packet_udphdr.it_src_port = 0x0A1A;/* 6666 */
        a_pcap_packet_udphdr.it_dst_port = 0x0202;/* 514 */
        a_pcap_packet_udphdr.it_len_payload = ((uint16)(i_nb_payload << 8) | (i_nb_payload >> 8));
        a_pcap_packet_udphdr.it_udp_checksum = 0;

        i_nb_payload = i_nb_payload + 20;
        a_pcap_packet_iphdr.it_ip_VHL = 0x45;
        a_pcap_packet_iphdr.it_ip_field = 0;
        a_pcap_packet_iphdr.it_nb_total = ((uint16)(i_nb_payload << 8) | (i_nb_payload >> 8));
        a_pcap_packet_iphdr.it_id_packet = gi_id_ippacket++;
        a_pcap_packet_iphdr.it_ip_flags = 0;
        a_pcap_packet_iphdr.it_ip_offset = 0;
        a_pcap_packet_iphdr.it_ip_TTL = 100;
        a_pcap_packet_iphdr.it_pl_protocol = 0x11;
        a_pcap_packet_iphdr.it_ip_checksum = 0;
        a_pcap_packet_iphdr.it_src_ipaddr = 0x5800A8C0;
        a_pcap_packet_iphdr.it_dst_ipaddr = 0x08080808;
        i_iphdr_checksum = lxzpcap_iphdr_checksum((uint16 *)(&a_pcap_packet_iphdr), sizeof(pcap_packet_iphdr_t));
        a_pcap_packet_iphdr.it_ip_checksum = i_iphdr_checksum;

        a_pcap_packet_mac.pt_dst_MAC[0] = 0x00;
        a_pcap_packet_mac.pt_dst_MAC[1] = 0x11;
        a_pcap_packet_mac.pt_dst_MAC[2] = 0x22;
        a_pcap_packet_mac.pt_dst_MAC[3] = 0x33;
        a_pcap_packet_mac.pt_dst_MAC[4] = 0x44;
        a_pcap_packet_mac.pt_dst_MAC[5] = 0x88;

        a_pcap_packet_mac.pt_src_MAC[0] = 0x00;
        a_pcap_packet_mac.pt_src_MAC[1] = 0x11;
        a_pcap_packet_mac.pt_src_MAC[2] = 0x22;
        a_pcap_packet_mac.pt_src_MAC[3] = 0x33;
        a_pcap_packet_mac.pt_src_MAC[4] = 0x44;
        a_pcap_packet_mac.pt_src_MAC[5] = 0x66;
        a_pcap_packet_mac.it_pl_protocol = 0x0008;

        gettimeofday(&(tv), (struct timezone *) NULL);
        i_nb_payload = i_nb_payload + 14;
        a_pcap_packethdr.it_capture_sec = tv.tv_sec;
        a_pcap_packethdr.it_capture_usec = tv.tv_usec;
        a_pcap_packethdr.it_capture_len = i_nb_payload;
        a_pcap_packethdr.it_actual_len = i_nb_payload;

        fwrite(&a_pcap_packethdr, 1, sizeof(pcap_packethdr_t), fp_fd_curfile);
        fwrite(&a_pcap_packet_mac, 1, sizeof(pcap_packet_mac_t), fp_fd_curfile);
        fwrite(&a_pcap_packet_iphdr, 1, sizeof(pcap_packet_iphdr_t), fp_fd_curfile);
        fwrite(&a_pcap_packet_udphdr, 1, sizeof(pcap_packet_udphdr_t), fp_fd_curfile);
        fwrite(llbuf, 1, i_nb_data, fp_fd_curfile);
        fflush(fp_fd_curfile);
    }

    return i_nb_data;
}

sint32 lxzpcap_sysloger_close(void)
{
    FILE* fp_fd_curfile = gfp_fd_sysloger;

    if (fp_fd_curfile != NULL)
    {
        fclose(fp_fd_curfile);
        gfp_fd_sysloger = fp_fd_curfile = NULL;
    }

    return 1;
}


